﻿using System;
using System.Collections.Generic;
using ESRI.ArcGIS.Server;

namespace DllShepherd.Core.Esri.Server
{
    public class ArcGisServerUtils
    {
        private const string ServiceConfigurationTypeName = "MapServer";

        public static void DeleteService(string serverName, string serviceName)
        {
            IGISServerConnection gisServerConnection = new GISServerConnectionClass();
            gisServerConnection.Connect(serverName);
            var serverObjectAdmin = gisServerConnection.ServerObjectAdmin;

            // start the service
            serverObjectAdmin.DeleteConfiguration(serviceName, ServiceConfigurationTypeName);
        }

        /// <summary>
        /// Returns the service's configuration in XML format
        /// Important if you want to examine and create your own
        /// </summary>
        /// <param name="serverName"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static string GetServiceConfiguration(string serverName, string serviceName)
        {
            IGISServerConnection gisServerConnection = new GISServerConnectionClass();
            gisServerConnection.Connect(serverName);
            var serverObjectAdmin = gisServerConnection.ServerObjectAdmin;

            var configuration = (IServerObjectConfiguration4)serverObjectAdmin.GetConfiguration(serviceName, ServiceConfigurationTypeName);

            return configuration.Serialize();
        }

        public static string ClearCache(string serverName, string userName, string password)
        {
            var result = HttpUtils.PostRequest("http://" + serverName + "/ArcGIS/rest/admin/login",
                                    new List<KeyValuePair<string, string>>
                                        {
                                            new KeyValuePair<string, string>("username", userName),
                                            new KeyValuePair<string, string>("password", password),
                                            new KeyValuePair<string, string>("redirect", String.Format("http%3a%2f%2f{0}%2fArcGIS%2frest%2fadmin%2fcache%2fclear", serverName)),
                                        }, String.Format("http://srvp7d-gtm/ArcGIS/rest/admin/login?redirect=http%3a%2f%2f{0}%2fArcGIS%2frest%2fadmin%2fcache%2fclear", serverName));

            //The response is in html, only return the response if its not a success
            return result.Contains("Cache Cleared.") ? "Cache Cleared." : result;
        }

        /// <summary>
        /// Publish map file (MSD or MXD) to server 
        /// </summary>
        /// <param name="mapFilePath">Either MSD or MXD</param>
        /// <param name="serverName"></param>
        /// <param name="serviceName"></param>
        public static void PublishToServer(string mapFilePath, string serverName, string serviceName)
        {
            IGISServerConnection gisServerConnection = new GISServerConnectionClass();
            gisServerConnection.Connect(serverName);
            var serverObjectAdmin = gisServerConnection.ServerObjectAdmin;
            var configuration = (IServerObjectConfiguration2)serverObjectAdmin.CreateConfiguration();

            // release the name of the Service, required
            configuration.Name = serviceName;
            // release the type of service, such as: MapServer, GeocodeServer
            configuration.TypeName = ServiceConfigurationTypeName;
            configuration.Description = serviceName;

            // Service Description
            SetDefaultServerConfigurations(configuration, mapFilePath, serverName); 

            // add service to the Server
            serverObjectAdmin.AddConfiguration(configuration);

            // start the service
            serverObjectAdmin.StartConfiguration(configuration.Name, configuration.TypeName);
        }

        private static void SetDefaultServerConfigurations(IServerObjectConfiguration2 configuration, string mapFilePath, string serverName)
        {
            var properties = configuration.Properties;
            // Set the path of the file
            properties.SetProperty("FilePath", mapFilePath);
            // image output directory
            properties.SetProperty("outputdir", "c:\\arcgisserver\\arcgisoutput");
            // image output virtual path
            properties.SetProperty("VirtualOutPutDir", "http://" + serverName + "/arcgisoutput");
            // image type supported by
            properties.SetProperty("SupportedImageReturnTypes", "URL");
            // maximum height of the picture
            properties.SetProperty("MaxImageHeight", "2048");
            // maximum number of records returned
            properties.SetProperty("MaxRecordCount", "50000");
            // maximum number of buffer analysis
            properties.SetProperty("MaxBufferCount", "100");
            // maximum width of the picture
            properties.SetProperty("MaxImageWidth", "2048");
            // is cached
            properties.SetProperty("IsCached", "false");
            // to take the slice
            properties.SetProperty("CacheOnDemand", "false");
            // is ignored slice
            properties.SetProperty("IgnoreCache", "false");
            // is client buffer allowed
            properties.SetProperty("ClientCachingAllowed", "true");
            // slice the output path
            properties.SetProperty("CacheDir", "c:\\arcgisserver\\arcgiscache\\NewService");
            // som slice output path
            properties.SetProperty("SOMCacheDir", "c:\\arcgisserver\\arcgiscache");

            configuration.IsolationLevel = esriServerIsolationLevel.esriServerIsolationHigh; 
            // if the pool of
            configuration.IsPooled = true;
            configuration.MaxInstances = 2;
            configuration.MinInstances = 1;

            // // Set the refresh
            var recycleProp = configuration.RecycleProperties;
            // refresh start time
            recycleProp.SetProperty("StartTime", "00:00");
            // refresh interval
            recycleProp.SetProperty("Interval", "3600");

            // // whether to open REST service
            var infoProp = configuration.Info;
            // REST services are provided
            infoProp.SetProperty("WebEnabled", "true");
            // what services provided
            infoProp.SetProperty("WebCapabilities", "Map, Query, Data");

            configuration.ExtensionEnabled["FeatureServer"] = true;
            configuration.ExtensionProperties["FeatureServer"].SetProperty("EnableZDefaults", "false");
            configuration.ExtensionProperties["FeatureServer"].SetProperty("ZDefaultValue", "0");
            configuration.ExtensionInfo["FeatureServer"].SetProperty("WebEnabled", "true");
            configuration.ExtensionInfo["FeatureServer"].SetProperty("SupportsMSD", "true");
            configuration.ExtensionInfo["FeatureServer"].SetProperty("WebCapabilities", "Query");
        }
    }
}
